package net.goutalk.glcs.module.system.controller;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.github.yulichang.toolkit.MPJWrappers;
import net.goutalk.glcs.common.constant.GlobalConstant;
import net.goutalk.glcs.common.model.result.R;
import net.goutalk.glcs.common.page.ConventPage;
import net.goutalk.glcs.common.page.PageInput;
import net.goutalk.glcs.common.page.PageOutput;
import net.goutalk.glcs.common.utils.VoToColumnUtil;
import net.goutalk.glcs.module.organization.entity.User;
import net.goutalk.glcs.module.system.dto.AddCodeRuleDto;
import net.goutalk.glcs.module.system.dto.UpdateCodeRuleDto;
import net.goutalk.glcs.module.system.entity.CodeRule;
import net.goutalk.glcs.module.system.service.ICodeRuleService;
import net.goutalk.glcs.module.system.vo.CodeRuleVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * <p>
 * 编号规则表 前端控制器
 * </p>
 *
 * @author zlf
 * @since 2022-06-23
 */
@Api(tags = "自动编码模块")
@RestController
@RequestMapping(GlobalConstant.SYSTEM_MODULE_PREFIX + "/code-rule")
@AllArgsConstructor
public class CodeRuleController {

    private ICodeRuleService codeRuleService;

    @ApiOperation(value = "获取编码规则分页")
    @GetMapping("/page")
    public R page(PageInput dto) {
        //因为多表关联 会有多个表都使用了id字段，  所以必须专门指定主表的Id,要使用创建用户createUserId去查询对应的用户名，并对应赋值给createUserName
        IPage<CodeRuleVo> page = codeRuleService.selectJoinListPage(ConventPage.getPage(dto), CodeRuleVo.class,
                MPJWrappers.<CodeRule>lambdaJoin()
                        .like(StrUtil.isNotBlank(dto.getKeyword()), CodeRule::getName, dto.getKeyword())
                        .select(CodeRule::getId)
                        .select(CodeRule.class, x -> VoToColumnUtil.fieldsToColumns(CodeRuleVo.class).contains(x.getProperty()))
                        .selectAs(User::getName, CodeRuleVo::getCreateUserName)
                        .leftJoin(User.class, User::getId, CodeRule::getCreateUserId)
                        .orderByAsc(CodeRule::getSortCode));

        PageOutput<CodeRuleVo> pageOutput = ConventPage.getPageOutput(page);
//        return R.ok(codeRuleService.getCodeRulePageList(dto));
        return R.ok(pageOutput);
    }

    @ApiOperation(value = "获取编码规则分页")
    @GetMapping("/list")
    public R list(@RequestParam(required = false) String keyword) {
        List<CodeRule> codeRuleList = codeRuleService.list(Wrappers.<CodeRule>query().lambda()
                .like(StrUtil.isNotBlank(keyword), CodeRule::getName, keyword));
        return R.ok(BeanUtil.copyToList(codeRuleList, CodeRuleVo.class));
    }

    @GetMapping("/info")
    @ApiOperation(value = "根据id 查询编码规则详情")
    @ApiImplicitParam(name = "编码规则id", value = "id", required = true, dataType = "string")
    public R info(@RequestParam String id) {
        CodeRule codeRule = codeRuleService.getById(id);
        return R.ok(BeanUtil.toBean(codeRule, CodeRuleVo.class));
    }

    @PostMapping
    @ApiOperation(value = "新增编码规则")
    public R add(@RequestBody AddCodeRuleDto addCodeRuleDto) {
        CodeRule codeRule = BeanUtil.toBean(addCodeRuleDto, CodeRule.class);
        codeRule.setCreateUserId(StpUtil.getLoginIdAsLong());
        return R.ok(codeRuleService.save(codeRule));
    }

    @PutMapping
    @ApiOperation(value = "修改编码规则")
    public R update(@RequestBody UpdateCodeRuleDto addCodeRuleDto) {
        CodeRule codeRule = BeanUtil.toBean(addCodeRuleDto, CodeRule.class);
        return R.ok(codeRuleService.updateById(codeRule));
    }

    @DeleteMapping
    @ApiOperation(value = "删除编码规则")
    @ApiImplicitParam(name = "编码规则id,多个用逗号隔开", value = "ids", required = true, dataType = "array")
    public R delete(@RequestBody List<Long> ids) {
        return R.ok(codeRuleService.removeByIds(ids));
    }

    @GetMapping("/generate")
    @ApiOperation(value = "生成自动编码")
    @ApiImplicitParam(name = "自动编码编号", value = "encode", required = true, dataType = "string")
    public R generate(@RequestParam String encode) {
        String code = codeRuleService.genEncode(encode);
        if (StrUtil.isEmpty(code)) {
            return R.error();
        }
        return R.ok(code);
    }

    @GetMapping("/use")
    @ApiOperation(value = "使用自动编码")
    @ApiImplicitParam(name = "自动编码编号", value = "encode", required = true, dataType = "string")
    public R use(@RequestParam String encode) {
        if (codeRuleService.useEncode(encode)) {
            return R.ok();
        }
        return R.error("没有编码可用，请生成！");
    }
}
